import { ref } from "vue";
import { Menu } from "@/models/Menu";
import api from "@/utils";
import { AxiosResponse } from "axios";
import { RoleMenuRelation } from "@/models/system/RoleMenuRelation";
import { ElMessage } from "element-plus/es";
import Scope from "@/models/Scope";
import { RoleBackendApiRelation } from "@/models/system/RoleBackendApiRelation";

export function MenuTree() {
  let type = "children";
  const menuTree = ref([] as Record<string, unknown>[]);
  const currentRoleId = ref();
  const menuTreeRef = ref();
  const selectedList = ref([] as Array<Record<string, unknown>>);
  const menuTreeProps = {
    children: "children",
    label: "title",
  };

  const setMenuTree = (data: Record<string, unknown>[]) => {
    menuTree.value = data;
  };
  const getMenuTree = () => {
    return menuTree.value;
  };

  const getMenuTreeData = (scoped: Scope) => {
    type = "children";
    menuTreeProps.children = "children";
    menuTreeProps.label = "title";
    api.http
      .get("/system/selectAllMenuTree")
      .then((res: AxiosResponse) => {
        setMenuTree(res.data.data);
      })
      .then(() => {
        currentRoleMenu(scoped);
      });
  };
  const getMenuBackendAPiTree = (scoped: Scope) => {
    type = "menuBackendApis";
    menuTreeProps.children = "menuBackendApis";
    menuTreeProps.label = "fullName";
    api.http
      .postJson("/system/selectMenuBackendApiTree", scoped.row.id)
      .then((res: AxiosResponse) => {
        setMenuTree(res.data.data);
      })
      .then(() => {
        currentRoleAuthorization(scoped);
      });
  };
  // 设置选择列表中的值
  const setSelectedList = () => {
    selectedList.value = [];
    const temp = type == "children" ? "title" : "fullName";
    menuTreeRef.value.getCheckedKeys().forEach((item: number) => {
      menuTree.value.forEach((menu: Record<string, unknown>) => {
        (menu[`${type}`] as []).forEach((children: Record<string, unknown>) => {
          if (item == children.id) {
            selectedList.value.push({
              title: children[temp],
              id: children.id,
            });
          }
        });
      });
    });
  };
  // 当前角色访问具体页面的具有操作权限
  const currentRoleAuthorization = (scoped: Scope) => {
    currentRoleId.value = scoped.row.id;
    api.http
      .get("/system/selectBackendAPiIdByRoleId/" + scoped.row.id)
      .then((res: AxiosResponse) => {
        menuTreeRef.value.setCheckedKeys(res.data.data);
        res.data.data.forEach((item: number) => {
          const node = menuTreeRef.value.getNode(item);
          if (
            node &&
            node.checked &&
            node.parent &&
            node.parent.checked == false
          ) {
            node.parent.checked = true;
          }
        });
      })
      .then(() => {
        setSelectedList();
      });
  };
  // 查询当前点击用户的菜单
  const currentRoleMenu = (scoped: Scope) => {
    currentRoleId.value = scoped.row.id;
    api.http
      .get("/system/selectMenuIdByRoleId/" + scoped.row.id)
      .then((res: AxiosResponse) => {
        menuTreeRef.value.setCheckedKeys(res.data.data);
      })
      .then(() => {
        setSelectedList();
      });
  };
  const selectedParent = (checkedNodes: Menu) => {
    const currentNode = menuTreeRef.value.getNode(checkedNodes);
    if (currentNode.parent.key !== undefined) {
      menuTreeRef.value.setChecked(currentNode.parent, true);
      selectedParent(currentNode.parent);
    }
  };
  const uniteChildSame = (treeList: Menu, isSelected: boolean) => {
    menuTreeRef.value.setChecked(treeList.id, isSelected);
    if (treeList[`${type}`]) {
      for (let i = 0; i < treeList[`${type}`].length; i++) {
        uniteChildSame(treeList[`${type}`][i], isSelected);
      }
    }
  };
  /**
   * 设置当前节点的父节点的勾选状态.
   */
  const setParentNodeValue = (checkedNodes: Menu) => {
    const currentNode = menuTreeRef.value.getNode(checkedNodes);
    let unchecked = true;
    currentNode.parent.childNodes.forEach((item: Record<string, unknown>) => {
      if (item.checked) {
        unchecked = false;
      }
    });
    if (unchecked) {
      menuTreeRef.value.setChecked(currentNode.parent, false);
    }
  };
  /**
   * 勾选项发生改变时, 重新设置选择的值
   * @param checkedNodes 当改变的勾选项
   * @param treeStatus 树结构当前的状态
   */
  const changeSelectedMenuIds = (
    checkedNodes: Menu,
    treeStatus: Record<string, Array<unknown>>
  ) => {
    // 用于：父子节点严格互不关联时，父节点勾选变化时通知子节点同步变化，实现单向关联。
    const selected = treeStatus.checkedKeys.indexOf(checkedNodes.id);
    if (selected !== -1) {
      // 子节点只要被选中父节点就被选中
      selectedParent(checkedNodes);
      // 统一处理子节点为相同的勾选状态
      uniteChildSame(checkedNodes, true);
    } else {
      setParentNodeValue(checkedNodes);
      // 父节点未选中时 使子节点全部未选中
      if (checkedNodes[`${type}`]?.length !== 0) {
        uniteChildSame(checkedNodes, false);
      }
    }
    setSelectedList();
  };

  const submitMenu = () => {
    if ("menuBackendApis" == type) {
      const roleBackendApiRelation = [] as RoleBackendApiRelation[];
      menuTreeRef.value.getCheckedKeys().forEach((item: number) => {
        roleBackendApiRelation.push({
          roleId: currentRoleId.value,
          backendApiId: item - 10000,
          createUser: sessionStorage.getItem("userName") as string,
          createGmt: new Date(),
        });
      });
      // 全不选的逻辑判断
      if (JSON.stringify(roleBackendApiRelation) == "[]") {
        roleBackendApiRelation.push({
          roleId: currentRoleId.value,
          backendApiId: -1,
          createUser: sessionStorage.getItem("userName") as string,
          createGmt: new Date(),
        });
      }
      api.http
        .postJson("/system/setRoleBackendApiRelation", roleBackendApiRelation)
        .then(() => {
          ElMessage.success("设置成功!");
        })
        .catch(() => {
          ElMessage.error("设置失败!");
        });
    } else {
      const roleMenuRelation = [] as RoleMenuRelation[];
      menuTreeRef.value.getCheckedKeys().forEach((item: number) => {
        roleMenuRelation.push({
          roleId: currentRoleId.value,
          menuId: item,
          createUser: sessionStorage.getItem("userName") as string,
          createGmt: new Date(),
        });
      });
      // 全不选的逻辑判断
      if (JSON.stringify(roleMenuRelation) == "[]") {
        roleMenuRelation.push({
          roleId: currentRoleId.value,
          menuId: -1,
          createUser: sessionStorage.getItem("userName") as string,
          createGmt: new Date(),
        });
      }
      api.http
        .postJson("/system/setRoleMenuRelation", roleMenuRelation)
        .then(() => {
          ElMessage.success("设置成功!");
        })
        .catch(() => {
          ElMessage.error("设置失败!");
        });
    }
  };
  // 当点击列表中的删除按钮时，删除列表中的当前点击数据，并且将el-tree中对应的节点设为非选择
  const removeSelectNode = (scope: Scope) => {
    selectedList.value.splice(scope.$index, 1);
    const checkNode = menuTreeRef.value.getNode(scope.row.id);
    const keyList = menuTreeRef.value.getCheckedKeys();
    keyList.splice(keyList.indexOf(scope.row.id), 1);
    menuTreeRef.value.setCheckedKeys(keyList);
    setParentNodeValue(checkNode);
  };
  // 全选
  const allChecked = () => {
    const idList = [] as Array<number>;
    selectedList.value = [];
    const temp = type == "children" ? "title" : "fullName";
    menuTree.value.forEach((menu: Record<string, unknown>) => {
      idList.push(menu.id as number);
      (menu[`${type}`] as []).forEach((children: Record<string, unknown>) => {
        selectedList.value.push({
          title: children[temp],
          id: children.id,
        });
        idList.push(children.id as number);
      });
    });
    menuTreeRef.value.setCheckedKeys(idList);
  };
  // 全不选
  const allNoChecked = () => {
    selectedList.value = [];
    menuTreeRef.value.setCheckedKeys([]);
  };
  return {
    menuTree,
    selectedList,
    getMenuTree,
    getMenuBackendAPiTree,
    menuTreeProps,
    menuTreeRef,
    submitMenu,
    allChecked,
    allNoChecked,
    getMenuTreeData,
    currentRoleMenu,
    currentRoleAuthorization,
    removeSelectNode,
    changeSelectedMenuIds,
  };
}
